//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2007
//
// System helpers.
//

# include "StdAfx.h"
# include "System.h"
# include "Trace.h"
# include "Wrappers.h"

enum TOKEN_INFORMATION_CLASS2 {
	TokenElevationType = 18,
	TokenLinkedToken,
	TokenElevation,
	TokenHasRestrictions,
	TokenAccessInformation,
	TokenVirtualizationAllowed,
	TokenVirtualizationEnabled,
	TokenIntegrityLevel,
	TokenUIAccess,
	TokenMandatoryPolicy,
	TokenLogonSid
};

struct TOKEN_ELEVATION {
	DWORD TokenIsElevated;
};

struct TOKEN_LINKED_TOKEN {
	HANDLE LinkedToken;
};

typedef WINADVAPI BOOL (WINAPI * pfOpenProcessToken_t) (HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
typedef WINADVAPI BOOL (WINAPI * pfGetTokenInformation_t) (HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength);

bool IsRunningUnderMSVistaWithStdPrivileges () {
	OSVERSIONINFO oi = {sizeof (OSVERSIONINFO)};
	::GetVersionEx (& oi);
	const bool bVista = oi.dwPlatformId == VER_PLATFORM_WIN32_NT && oi.dwMajorVersion >= 6;
	if (! bVista)
		return false;

	const HMODULE hAdvApi32 = ::GetModuleHandle ("Advapi32.dll");
	if (hAdvApi32 == NULL)
		return false;
	const pfOpenProcessToken_t    pfOpenProcessToken    = (pfOpenProcessToken_t)    ::GetProcAddress (hAdvApi32, "OpenProcessToken");
	const pfGetTokenInformation_t pfGetTokenInformation = (pfGetTokenInformation_t) ::GetProcAddress (hAdvApi32, "GetTokenInformation");
	if (pfOpenProcessToken == NULL || pfGetTokenInformation == NULL)
		return false;

	HANDLE hToken = NULL;
	if (! pfOpenProcessToken (::GetCurrentProcess (), TOKEN_QUERY, & hToken)) {
		TRACE_LAST_ERROR ();
		return false;
	}
	CWinHandle hToken_Wrapper (hToken);

	TOKEN_ELEVATION te;
	::memset (& te, 0, sizeof (te));
	DWORD dwSize = 0;
	if (! pfGetTokenInformation (hToken, (TOKEN_INFORMATION_CLASS) TokenElevation, & te, sizeof (te), & dwSize)) {
		TRACE_LAST_ERROR ();
		return false;
	}
	if (te.TokenIsElevated != 0)
		return false;

	return true;

/*	TOKEN_LINKED_TOKEN lt;
	::memset (& lt, 0, sizeof (lt));
	dwSize = 0;
	if (! ::GetTokenInformation (hThreadToken, (TOKEN_INFORMATION_CLASS) TokenLinkedToken, & lt, sizeof (lt), & dwSize)) {
		TRACE_LAST_ERROR ();
		return;
	}*/
}

////////////////////////////////////////////////////////

/*void SetDebugPrivilege () {
	// Get security tonen.
	HANDLE hToken = NULL;
	::OpenProcessToken (::GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, & hToken);
	CWinHandle hTokenGuard (hToken);

	TOKEN_PRIVILEGES tp;
	LUID luid;
	TOKEN_PRIVILEGES tpPrevious;
	DWORD cbPrevious = sizeof (TOKEN_PRIVILEGES);
	if (! ::LookupPrivilegeValue (NULL, SE_DEBUG_NAME, & luid))
		return;

	// Get current privilege setting.
	tp.PrivilegeCount            = 1;
	tp.Privileges [0].Luid       = luid;
	tp.Privileges [0].Attributes = 0;
	if (! ::AdjustTokenPrivileges (hToken, FALSE, & tp,	sizeof (TOKEN_PRIVILEGES), & tpPrevious, & cbPrevious))
		return;

	// Set privilege based on previous setting.
	tpPrevious.PrivilegeCount      = 1;
	tpPrevious.Privileges [0].Luid = luid;
	tpPrevious.Privileges [0].Attributes |= SE_PRIVILEGE_ENABLED;
	::AdjustTokenPrivileges (hToken, FALSE, & tpPrevious, cbPrevious, NULL,	NULL);
}*/
